package com.system.uitls;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;

public class SearchFilter
{
  private Operator oprt;
  private String fieldName;
  private String[] values;
  private String mapName;

  public SearchFilter()
  {
  }

  public SearchFilter(Operator oprt, String fieldName, String[] values, String mapName)
  {
    this.oprt = oprt;
    this.fieldName = fieldName;
    this.values = values;
    this.mapName = mapName;
  }

  public String getMapName()
  {
    return this.mapName;
  }

  public void setMapName(String mapName)
  {
    this.mapName = mapName;
  }

  public String[] getValues() {
    return this.values;
  }

  public void setValues(String[] values) {
    this.values = values;
  }

  public Operator getOprt() {
    return this.oprt;
  }

  public void setOprt(Operator oprt) {
    this.oprt = oprt;
  }

  public String getFieldName() {
    return this.fieldName;
  }

  public void setFieldName(String fieldName) {
    this.fieldName = fieldName;
  }

  public static String getSearchSql(Map<String, Object> params, String alias)
  {
    StringBuilder sb = new StringBuilder("");

    Map map = new HashMap();
    Object object;
    for (Iterator it = params.keySet().iterator(); it.hasNext(); )
    {
      String key = (String)it.next();

      if (!key.startsWith("search_"))
      {
        continue;
      }
      object = params.get(key);
      String[] array = (String[])null;

      if ((object instanceof String))
      {
        String value = CommonUtil.nullToEmptyString(object);
        if (!"".equals(value))
        {
          array = new String[] { value };
        }
      }
      else if ((object instanceof String[]))
      {
        array = (String[])object;
      }
      else if ((object instanceof List)) {
        array = (String[])((List)object).toArray();
      }
      else {
        array = new String[0];
      }

      map.put(key, array);
    }

    List<SearchFilter> filters = parse(map, alias);

    for (SearchFilter sf : filters)
    {
      switch (sf.oprt) {
      case EQ:
        sb.append(" and ").append(sf.fieldName).append("=:").append(sf.mapName);
        break;
      case CONTAIN:
        sb.append(" and ").append(sf.fieldName).append(" like ").append(":").append(sf.mapName);
        params.put(sf.mapName, "%" + sf.values[0] + "%");
        break;
      case STARTWITH:
        sb.append(" and ").append(sf.fieldName).append(" like ").append(":").append(sf.mapName);
        params.put(sf.mapName, sf.values[0] + "%");
        break;
      case ENDWITH:
        sb.append(" and ").append(sf.fieldName).append(" like ").append(":").append(sf.mapName);
        params.put(sf.mapName, "%" + sf.values[0]);
        break;
      case GT:
        sb.append(" and ").append(sf.fieldName).append(">:").append(sf.mapName);
        break;
      case LT:
        sb.append(" and ").append(sf.fieldName).append("<:").append(sf.mapName);
        break;
      case GTE:
        sb.append(" and ").append(sf.fieldName).append(">=:").append(sf.mapName);
        break;
      case LTE:
        sb.append(" and ").append(sf.fieldName).append("<=:").append(sf.mapName);
        break;
      case IN:
        sb.append(" and ").append(sf.fieldName).append(" in ").append(sf.mapName);
        StringBuffer buffer = new StringBuffer("");

        for (String str : sf.values)
        {
          if (buffer.length() > 0)
          {
            buffer.append(",").append(str);
          }
          else buffer.append(str);
        }

        params.put(sf.mapName, "(" + buffer.toString() + ")");
      }

    }

    return sb.toString();
  }

  public static List<SearchFilter> parse(Map<String, String[]> params, String alias)
  {
    if ((params == null) || (params.isEmpty())) {
      return Collections.emptyList();
    }

    if (alias == null)
    {
      alias = "";
    }
    else alias = alias + ".";

    List filters = new ArrayList();

    for (Map.Entry entry : params.entrySet())
    {
      String key = (String)entry.getKey();
      String[] values = (String[])entry.getValue();
      if (ArrayUtils.isEmpty(values))
      {
        continue;
      }

      String[] names = StringUtils.split(key, "_");
      if (names.length < 3) {
        throw new IllegalArgumentException(key + " 查询字符串格式有误");
      }

      Operator operator = Operator.valueOf(names[1]);

      String filedName = "";
      for (int i = 2; i < names.length; i++)
      {
        filedName = filedName + names[i] + "_";
      }

      filedName = filedName.substring(0, filedName.length() - 1);
      filters.add(new SearchFilter(operator, alias + filedName, values, key));
    }

    return filters;
  }

  public static enum Operator
  {
    EQ, CONTAIN, STARTWITH, ENDWITH, GT, LT, GTE, LTE, IN;
  }
}